﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;


namespace DesertEagleQuest
{
    class Ship
    {

        #region Declarations

        private const float MinimumAltitude = 350.0f;

        Vector3 MAX = new Vector3(70000, 0, 70000);
        Vector3 MIN = new Vector3(-70000, 0, -70000); 
               
        private GraphicsDevice graphicsDevice;
        public Vector3 Position;
        public Vector3 Direction;
        public Vector3 Up;
        private Vector3 right;
        private Vector3 Velocity;
        
        private const float RotationRate = 1.5f;
        private const float Mass = 1.0f;     
        private const float ThrustForce = 24000.0f;
        private const float DragFactor = 0.97f;

        #endregion 

        #region Getter /Setter

        public Matrix World
        {
            get { return world; }
        }
        private Matrix world;


        public Vector3 GetPosition
        {
            get { return Position; }
        }

        public Vector3 GetVelocity
        {
            get { return Velocity; }
            set { Velocity = value; }
        }

        public Vector3 Right
        {
            get { return right; }
        }



        #endregion 

        #region Constructor

        public Ship(GraphicsDevice device)
        {
            graphicsDevice = device;
            Reset();
        }

        /// <summary>
        /// Restore the ship to its original starting state
        /// </summary>
        public void Reset()
        {
            Position = new Vector3(0, MinimumAltitude, 0);
            Direction = Vector3.Forward;
            Up = Vector3.Up;
            right = Vector3.Right;
            Velocity = Vector3.Zero;

        }

        #endregion

        #region Update

        public void Update(GameTime gameTime)
        {
            GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
            float elapsed = (float) gameTime.ElapsedGameTime.TotalSeconds;

            checkIfOutOfSideMap(); 


            Vector2 rotationAmount = -gamePadState.ThumbSticks.Left;

            rotationAmount = rotationAmount * RotationRate * elapsed;

            Matrix rotationMatrix =
                Matrix.CreateFromAxisAngle(Right, rotationAmount.Y) *
                Matrix.CreateRotationY(rotationAmount.X);

            Direction = Vector3.TransformNormal(Direction, rotationMatrix);
            Up = Vector3.TransformNormal(Up, rotationMatrix);

            Direction.Normalize();
            Up.Normalize();

            right = Vector3.Cross(Direction, Up);
            Up = Vector3.Cross(Right, Direction);

            float thrustAmount = gamePadState.Triggers.Right;
            
            Vector3 force = Direction * thrustAmount * ThrustForce;
            Vector3 acceleration = force / Mass;
            Velocity += acceleration * elapsed;
            Velocity *= DragFactor;
            Position += Velocity * elapsed;

            Position.Y = Math.Max(Position.Y, MinimumAltitude);

            world = Matrix.Identity;
            world.Forward = Direction;
            world.Up = Up;
            world.Right = right;
            world.Translation = Position;

        }


        #endregion 

        #region HelperMethods

        public void checkIfOutOfSideMap()
        {           

            if(Position.X >= MAX.X || Position.X < MIN.X)
                Velocity *= -1;

            if (Position.Z >= MAX.Z || Position.Z < MIN.Z)
                Velocity *= -1; 
        }


        #endregion 
                
    }
}
